#include <iostream>
#include "reverse_iterator.hpp"
namespace YX 
{
    template<typename T>
    class vector 
    {
        public:
            typedef T* iterator;
            typedef const T* const_iterator;
            typedef Reverse_Iterator<iterator,T&,T*> reverse_iterator;

            vector()
                :_start(nullptr)
                ,_finish(nullptr)
                ,_end(nullptr)
            {

            }

            bool empty()
            {
                return _start==_finish;
            }

            size_t capacity()
            {
                return _end-_start;
            }

            size_t size()
            {
                return _finish-_start;
            }

            bool full()
            {
                return _finish==_end;
            }

            void reserve(size_t n)
            {
                if(n>capacity())
                {

                    size_t sz=size();

                    iterator tmp = new T[n];

                    for(size_t i=0;i<sz;i++)
                    {
                        tmp[i]=_start[i];
                    }

                    if(_start)
                    {
                        delete[] _start;
                    }

                    _start=tmp;

                    _finish=tmp+sz;
                    _end=tmp+n;

                }
            }

            void push_back(const T& val)
            {
                if(full())
                {
                    reserve(_start==nullptr?4:2*capacity());
                }

                *_finish=val;

                _finish++;

            }

            iterator begin()
            {
                return _start;
            }

            iterator end()
            {
                return _finish;
            }

            reverse_iterator rbegin()
            {
                return reverse_iterator(end());
            }

            reverse_iterator rend()
            {
                return reverse_iterator(begin());
            }


        private:
            iterator _start;
            iterator _finish;
            iterator _end;
    };


};

namespace YX 
{
    template<typename T>
    struct ListNode
    {
        typedef ListNode<T> Node;
        Node* _prev;
        Node* _next;
        T _data;

        ListNode(const T& data)
            :_data(data)
        {
            _prev=this;
            _next=this;
        }
    };

    template<class T,class Ref,class Ptr>
    class List_Iterator
    {
        typedef ListNode<T> Node;

        typedef List_Iterator<T,Ref,Ptr> Iterator;

        private:
            Node* _pNode;
        public:
            
            List_Iterator(Node* pNode)
                :_pNode(pNode)
            {

            }

            Iterator& operator++()
            {
                _pNode=_pNode->_next;

                return *this;
            }

            Iterator& operator--()
            {
                _pNode=_pNode->_prev;

                return *this;
            }

            Ref operator*()
            {
                return _pNode->_data;
            }

            Ptr operator->()
            {
                return &(operator*());
            }

            bool operator!=(Iterator it)
            {
                return _pNode!=it._pNode;
            }

    };


    template<class T>
    class List 
    {
        private:
            typedef ListNode<T> Node;
            
            Node* _phead;

        public: 

            typedef List_Iterator<T,T&,T*> iterator;
            typedef Reverse_Iterator<iterator,T&,T*> reverse_iterator;


            List()
                :_phead(new Node(T()))
            {

            }

            void push_back(const T& val)
            {
                Node* tail=_phead->_prev;

                Node* newNode=new Node(val);

                tail->_next=newNode;
                newNode->_prev=tail;

                _phead->_prev=newNode;
                newNode->_next=_phead;
            }

            iterator begin()
            {
                return iterator(_phead->_next);
            }

            iterator end()
            {
                return iterator(_phead);
            }

            reverse_iterator rbegin()
            {
                return reverse_iterator(end());
            }

            reverse_iterator rend()
            {
                return reverse_iterator(begin());
            }

    };




};
